iT邦幫忙

2022 iThome 鐵人賽

DAY 22
1
Software Development

React框架白話文運動系列 第 22

React白話文運動22-React Hook-useReducer

  • 分享至 

  • xImage
  •  

前言

嗨,我是Hogan
目前在經營自己的自媒體 hogan.tech
主要分享一些有關於程式碼、軟體和科技業經驗分享
有興趣的讀者可以進一步關注我,進而獲得更多資訊唷!

未來文章一併更新於此網站 Hogan.B Lab
並且包含多語系 繁體中文英文日文簡體中文
觀看分類:React 白話文運動其他系列

如果想要快速查找其他文章請點選目錄

成立 hogan.tech 的初衷是
希望每個正在這條路上探索的人,
都可以透過 Hogan.tech 嘗試進入程式領域。


前一篇會介紹另一個與useEffect 很像的Hook - useLayoutEffect

  1. 複習 useEffect
  2. 使用 useLayoutEffect
  3. Hook 的使用原則

這一篇終於來到Hook系列的最後一個Hook - useReducer

  1. useState 的寫法
  2. useResucer 的寫法
  3. class component 的寫法

useState 的寫法

一樣在講解新的語法之前,都會使用已熟悉的Hook 來去做範例講解

這次的範例是給予一個物件資料,並且使用一個按鈕來去做值得修改

以下是我們的範例資料,為一個User的物件

裡面包含了名字、電子信箱、國家

const UserData = {
    userName: "Hogan",
    email: "hoganlin.tech@gmail.com",
    country: "Taiwan"
}

以下也建立一個元件稱為 User,並且會顯示所有物件的資訊

其中也建立一個按鈕,期望點擊之後可以將原有物件的姓名 Hogan 修改為 Bobo

function User() {
    const [user, setUser] = useState(UserData)
    return (
        <div>
            <h1>{`Name: ${user.userName}`}</h1>
            <h1>{`Email: ${user.email}`}</h1>
            <h1>{`Country: ${user.country}`}</h1>
            <button> Change Name to BOBO</button>
        </div>
    )
}

我們一般認知上,會選擇直接將userName 修改為 bobo

然而實際上是不能這樣去修改的

這樣會導致整個物件原本有名稱、電子郵件、國家,被修改完後,只會剩下名稱

<button onClick={setUser({ userName: "Bobo" })}>
	Change Name to BOBO
</button>

這邊應該使用的方法是除了欲更新的名稱欄位以外

也應該用延展運算子來去做資料的儲存,再去更新對應的名稱欄位

<button onClick={setUser({ ...user, userName: "Bobo" })}>
	Change Name to BOBO
</button>

useResucer 的寫法

看到上述的例子,可以發現必須要使用延展運算子才能做物件的更新

那麼有沒有更直覺的寫法,如同:

<button onClick={setUser({ userName: "Bobo" })}>
	Change Name to BOBO
</button>

答案當然是有的,那就是使用 useReducer

方法是類似useState ,一樣會有 user 以及 setUser

裡面傳遞的參數,以下面為例子有兩個引數,分別為一個箭頭函式以及一個初始資料

箭頭韓式則是會有兩個引數,分別為當前的 user 資料以及欲更新的資料newDetail

const [user, setUser] = useReducer(
   	(user, newDetail) => ({ ...user, ...newDetail })
    , UserData);

接下來,按鈕方面就可以直接使用直覺的寫法

<button onClick={setUser({ userName: "Bobo" })}>
	Change Name to BOBO
</button>

以下也提供完整的useReducer程式碼,讓讀者做參考

import React, { useReducer } from 'react';

const UserData = {
    userName: "Hogan",
    email: "hoganlin.tech@gmail.com",
    country: "Taiwan"
}

function User() {
    const [user, setUser] = useReducer(
        (user, newDetail) => ({ ...user, ...newDetail })
        , UserData);
    return (
        <div>
            <h1>{`Name: ${user.userName}`}</h1>
            <h1>{`Email: ${user.email}`}</h1>
            <h1>{`Country: ${user.country}`}</h1>
            <button onClick={setUser({userName: "Bobo"})}>Change Name to BOBO</button>
        </div>
    )
}

class component 的寫法

最後也附上如果是早期類別元件的寫法,那麼他們是如何做到一樣的事情

首先因為是類別,所以需要定義建構子,並且把相對應的值放入 this.state 中

最後在按鈕中,使用箭頭函式,將綁定的setting 函數置入,就可以去修改類別的狀態

class UserOld extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            userName: "Hogan",
            email: "hoganlin.tech@gmail.com",
            country: "Taiwan"
        }
    }
}

<button onClick={() => this.setState({ userName: "Bobo" })}>Change Name to BOBO</button>

讀者也可以比較以下 useReducer 的寫法,會發現滿不同的

我也滿推薦useReducer的寫法,其用意是在將複雜的狀態處理寫法,寫得更簡潔

const [user, setUser] = useReducer(
        (user, newName) => ({ ...user, ...newName })
        , UserData);


<button onClick={setUser({userName: "Bobo"})}>Change Name to BOBO</button>


結語

這一篇講解了 useReducer 的使用方法

也給了 useState 以及類別元件的處理方法

如果有任何建議與疑問也歡迎留言!

如果喜歡此系列文章,請不吝於按下喜歡及分享,讓更多人看到唷~
React白話文運動22-React Hook-useReducer


上一篇
React白話文運動21-React Hook-useLayoutEffect
下一篇
React白話文運動23-Flux 概念
系列文
React框架白話文運動30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言